package j2025.j04;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

/**
 * @Author 猫大仙
 */
class Trie {

    private Trie[] children;
    private boolean isEnd;
    public Trie() {
        isEnd = false;
        children = new Trie[26];
    }

    public void insert(String word) {
        Trie node = this;
        for(char ch:word.toCharArray()){
            if(node.children[ch-'a']==null){
                node.children[ch-'a'] = new Trie();
            }
            node = node.children[ch-'a'];
        }
        node.isEnd = true;
    }

    public boolean search(String word) {
        Trie node = this;
        for(char ch:word.toCharArray()){
            node =  node.children[ch-'a'];
            if(node == null){
                return false;
            }
        }
        return node.isEnd;
    }

    public boolean startsWith(String prefix) {
        Trie node = this;
        for(char ch:prefix.toCharArray()){
            node =  node.children[ch-'a'];
            if(node == null){
                return false;
            }
        }
        return true;
    }
}

public class j0425 {




    public class MagicArray {
        static class Edge implements Comparable<Edge> {
            int u, v;
            double weight;

            public Edge(int u, int v, double weight) {
                this.u = u;
                this.v = v;
                this.weight = weight;
            }

            @Override
            public int compareTo(Edge o) {
                return Double.compare(this.weight, o.weight); // 按权重升序排序
            }
        }

        static class UnionFind {
            int[] parent;

            public UnionFind(int n) {
                parent = new int[n];
                for (int i = 0; i < n; i++) parent[i] = i;
            }

            // 路径压缩查找根节点
            public int find(int x) {
                if (parent[x] != x) parent[x] = find(parent[x]);
                return parent[x];
            }

            // 合并两个集合
            public void union(int x, int y) {
                int rootX = find(x), rootY = find(y);
                if (rootX != rootY) parent[rootX] = rootY;
            }
        }

        public static double minMagicPath(int n, int[][] arrays) {
            List<Edge> edges = new ArrayList<>();
            for (int i = 0; i < n; i++) {
                for (int j = i + 1; j < n; j++) {
                    // 计算圆心距离
                    double dx = arrays[i][0] - arrays[j][0];
                    double dy = arrays[i][1] - arrays[j][1];
                    double dist = Math.sqrt(dx * dx + dy * dy);

                    // 计算边权重
                    double weight = dist - (arrays[i][2] + arrays[j][2]);
                    if (weight < 0) weight = 0; // 处理相交或内含的情况
                    edges.add(new Edge(i, j, weight));
                }
            }

            // 按边权重排序
            Collections.sort(edges);

            UnionFind uf = new UnionFind(n);
            double total = 0;
            for (Edge edge : edges) {
                if (uf.find(edge.u) != uf.find(edge.v)) {
                    total += edge.weight;
                    uf.union(edge.u, edge.v);
                }
            }
            return total;
        }

        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            int n = scanner.nextInt();
            int[][] arrays = new int[n][3];
            for (int i = 0; i < n; i++) {
                arrays[i][0] = scanner.nextInt(); // x坐标
                arrays[i][1] = scanner.nextInt(); // y坐标
                arrays[i][2] = scanner.nextInt(); // 半径
            }
            System.out.printf("%.2f\n", minMagicPath(n, arrays)); // 保留两位小数输出
        }
    }
}
